﻿#include "input.h"
#include <iostream>

InputHandler::InputHandler() : mouseX(0), mouseY(0), mouseWheelDelta(0) {
    // 初始化所有按键状态为释放
    for (int i = 0; i < 256; ++i) {
        keyStates[i] = KeyState::Released;
        prevKeyStates[i] = KeyState::Released;
    }

    // 初始化鼠标按钮状态
    mouseStates[MouseButton::Left] = KeyState::Released;
    mouseStates[MouseButton::Right] = KeyState::Released;
    mouseStates[MouseButton::Middle] = KeyState::Released;

    prevMouseStates[MouseButton::Left] = KeyState::Released;
    prevMouseStates[MouseButton::Right] = KeyState::Released;
    prevMouseStates[MouseButton::Middle] = KeyState::Released;
}

void InputHandler::update() {
    // 保存上一帧的状态
    prevKeyStates = keyStates;
    prevMouseStates = mouseStates;
    mouseWheelDelta = 0;

    // 清空事件队列
    eventQueue.clear();

    // 处理所有待处理的消息
    ExMessage msg;
    while (peekmessage(&msg)) {
        switch (msg.message) {
        case WM_KEYDOWN:
            // 更新按键状态
            keyStates[msg.vkcode] = KeyState::JustPressed;

            // 添加键盘按下事件
            InputEvent event;
            event.type = InputEventType::KeyDown;
            event.keyCode = msg.vkcode;
            eventQueue.push_back(event);
            break;

        case WM_KEYUP:
            // 更新按键状态
            keyStates[msg.vkcode] = KeyState::JustReleased;

            // 添加键盘释放事件
            event.type = InputEventType::KeyUp;
            event.keyCode = msg.vkcode;
            eventQueue.push_back(event);
            break;

        case WM_MOUSEMOVE:
            // 更新鼠标位置
            mouseX = msg.x;
            mouseY = msg.y;

            // 添加鼠标移动事件
            event.type = InputEventType::MouseMove;
            event.mouse.x = msg.x;
            event.mouse.y = msg.y;
            eventQueue.push_back(event);
            break;

        case WM_LBUTTONDOWN:
            // 更新鼠标左键状态
            mouseStates[MouseButton::Left] = KeyState::JustPressed;

            // 添加鼠标按下事件
            event.type = InputEventType::MouseDown;
            event.mouse.x = msg.x;
            event.mouse.y = msg.y;
            event.mouse.button = MouseButton::Left;
            eventQueue.push_back(event);
            break;

        case WM_LBUTTONUP:
            // 更新鼠标左键状态
            mouseStates[MouseButton::Left] = KeyState::JustReleased;

            // 添加鼠标释放事件
            event.type = InputEventType::MouseUp;
            event.mouse.x = msg.x;
            event.mouse.y = msg.y;
            event.mouse.button = MouseButton::Left;
            eventQueue.push_back(event);
            break;

        case WM_RBUTTONDOWN:
            // 更新鼠标右键状态
            mouseStates[MouseButton::Right] = KeyState::JustPressed;

            // 添加鼠标按下事件
            event.type = InputEventType::MouseDown;
            event.mouse.x = msg.x;
            event.mouse.y = msg.y;
            event.mouse.button = MouseButton::Right;
            eventQueue.push_back(event);
            break;

        case WM_RBUTTONUP:
            // 更新鼠标右键状态
            mouseStates[MouseButton::Right] = KeyState::JustReleased;

            // 添加鼠标释放事件
            event.type = InputEventType::MouseUp;
            event.mouse.x = msg.x;
            event.mouse.y = msg.y;
            event.mouse.button = MouseButton::Right;
            eventQueue.push_back(event);
            break;

        case WM_MBUTTONDOWN:
            // 更新鼠标中键状态
            mouseStates[MouseButton::Middle] = KeyState::JustPressed;

            // 添加鼠标按下事件
            event.type = InputEventType::MouseDown;
            event.mouse.x = msg.x;
            event.mouse.y = msg.y;
            event.mouse.button = MouseButton::Middle;
            eventQueue.push_back(event);
            break;

        case WM_MBUTTONUP:
            // 更新鼠标中键状态
            mouseStates[MouseButton::Middle] = KeyState::JustReleased;

            // 添加鼠标释放事件
            event.type = InputEventType::MouseUp;
            event.mouse.x = msg.x;
            event.mouse.y = msg.y;
            event.mouse.button = MouseButton::Middle;
            eventQueue.push_back(event);
            break;

        case WM_MOUSEWHEEL:
            // 更新鼠标滚轮状态
            mouseWheelDelta = GET_WHEEL_DELTA_WPARAM(msg.wParam);

            // 添加鼠标滚轮事件
            event.type = InputEventType::MouseWheel;
            event.mouse.x = msg.x;
            event.mouse.y = msg.y;
            event.mouse.wheelDelta = mouseWheelDelta;
            eventQueue.push_back(event);
            break;
        }
    }

    // 更新按键和鼠标状态
    for (auto& pair : keyStates) {
        if (pair.second == KeyState::JustPressed) {
            pair.second = KeyState::Pressed;
        }
        else if (pair.second == KeyState::JustReleased) {
            pair.second = KeyState::Released;
        }
    }

    for (auto& pair : mouseStates) {
        if (pair.second == KeyState::JustPressed) {
            pair.second = KeyState::Pressed;
        }
        else if (pair.second == KeyState::JustReleased) {
            pair.second = KeyState::Released;
        }
    }

    // 触发所有注册的回调函数
    for (const auto& event : eventQueue) {
        auto it = eventCallbacks.find(event.type);
        if (it != eventCallbacks.end()) {
            for (const auto& callback : it->second) {
                callback(event);
            }
        }
    }
}

bool InputHandler::isKeyDown(int keyCode) const {
    auto it = keyStates.find(keyCode);
    return it != keyStates.end() &&
        (it->second == KeyState::Pressed || it->second == KeyState::JustPressed);
}

bool InputHandler::isKeyUp(int keyCode) const {
    auto it = keyStates.find(keyCode);
    return it != keyStates.end() &&
        (it->second == KeyState::Released || it->second == KeyState::JustReleased);
}

bool InputHandler::wasKeyPressed(int keyCode) const {
    auto it = keyStates.find(keyCode);
    auto prevIt = prevKeyStates.find(keyCode);
    return it != keyStates.end() && prevIt != prevKeyStates.end() &&
        it->second == KeyState::JustPressed &&
        prevIt->second == KeyState::Released;
}

bool InputHandler::wasKeyReleased(int keyCode) const {
    auto it = keyStates.find(keyCode);
    auto prevIt = prevKeyStates.find(keyCode);
    return it != keyStates.end() && prevIt != prevKeyStates.end() &&
        it->second == KeyState::JustReleased &&
        prevIt->second == KeyState::Pressed;
}

bool InputHandler::isMouseButtonDown(MouseButton button) const {
    auto it = mouseStates.find(button);
    return it != mouseStates.end() &&
        (it->second == KeyState::Pressed || it->second == KeyState::JustPressed);
}

bool InputHandler::isMouseButtonUp(MouseButton button) const {
    auto it = mouseStates.find(button);
    return it != mouseStates.end() &&
        (it->second == KeyState::Released || it->second == KeyState::JustReleased);
}

bool InputHandler::wasMouseButtonPressed(MouseButton button) const {
    auto it = mouseStates.find(button);
    auto prevIt = prevMouseStates.find(button);
    return it != mouseStates.end() && prevIt != prevMouseStates.end() &&
        it->second == KeyState::JustPressed &&
        prevIt->second == KeyState::Released;
}

bool InputHandler::wasMouseButtonReleased(MouseButton button) const {
    auto it = mouseStates.find(button);
    auto prevIt = prevMouseStates.find(button);
    return it != mouseStates.end() && prevIt != prevMouseStates.end() &&
        it->second == KeyState::JustReleased &&
        prevIt->second == KeyState::Pressed;
}

int InputHandler::getMouseX() const {
    return mouseX;
}

int InputHandler::getMouseY() const {
    return mouseY;
}

int InputHandler::getMouseWheelDelta() const {
    return mouseWheelDelta;
}

void InputHandler::registerCallback(InputEventType type, const std::function<void(const InputEvent&)>& callback) {
    eventCallbacks[type].push_back(callback);
}

void InputHandler::clearEvents() {
    eventQueue.clear();
}